package com.hna.face.controller;

import com.alibaba.fastjson.JSON;
import com.baomidou.mybatisplus.mapper.EntityWrapper;
import com.baomidou.mybatisplus.mapper.Wrapper;
import com.hna.face.base.BaseResult;
import com.hna.face.config.SysConfig;
import com.hna.face.model.*;
import com.hna.face.mqtt.MqttService;
import com.hna.face.service.*;
import org.apache.tomcat.util.codec.binary.Base64;
import org.eclipse.paho.client.mqttv3.MqttException;
import org.eclipse.paho.client.mqttv3.MqttMessage;
import org.eclipse.paho.client.mqttv3.MqttPersistenceException;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import java.io.File;
import java.io.FileInputStream;
import java.io.InputStream;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;

//import org.slf4j.Logger;
//import org.slf4j.LoggerFactory;

//@Controller
@RestController
@RequestMapping(value = "/faceApi")
public class FaceServiceController {

	private final static Logger log = LoggerFactory.getLogger(FaceServiceController.class);

	@Autowired
	MqttService service;

	@Autowired
	private IFaceSyncInfoService syncInfoservice;

	@Autowired
	private IFaceVehicleService faceVehicleService;

	@Autowired
	private IFaceScheduleService faceScheduleService;

	@Autowired
	private IFacePersonService facePersonService;

	@Autowired
	private IFacePhotoLibService facePhotoLibService;

	@Autowired
	private IFaceSyncTaskService taskService;

	// @PostMapping(value = "/test")
	public BaseResult test() {
		try {
//			service.startReconnect();
			MqttMessage message = new MqttMessage();
			message.setQos(1);
			message.setRetained(true);
			message.setPayload("初始化成功".getBytes());
			service.publish(message, "will");
			log.info(message.isRetained() + "------ratained状态");
//			service.subscribe();

		} catch (MqttException e1) {
			// TODO Auto-generated catch block
			log.error("mqttinit1", e1);
		} catch (Error e1) {
			// TODO Auto-generated catch block
			log.error("mqttinit2", e1);
		}
		BaseResult baseResult = BaseResult.success();

		return baseResult.success();
	}

	/**
	 * 
	 * @throws MqttPersistenceException
	 * @throws MqttException
	 * 
	 *                                  发送车俩信息，人员（数组）信息，照片（数组）信息，排班(数组)信息
	 * 
	 */
	
	@Scheduled(cron = "${face-sync-schedule}", zone = "${time-zone}")
	@PostMapping(value = "/sync")
	public BaseResult sync() {
		BaseResult baseResult = BaseResult.success();
		StringBuilder result = new StringBuilder();

		try {
			Wrapper<FaceSyncInfo> syncInfoWrapper = new EntityWrapper<>();
			syncInfoWrapper.eq("status", 1);
			List<FaceSyncInfo> syncInfoList = syncInfoservice.selectList(syncInfoWrapper);
			for(FaceSyncInfo syncInfo:syncInfoList) {
				FaceSyncTask syncTask=new FaceSyncTask();
				syncTask.setVehicleNo("xy-003");
				syncTask.setTableName(syncInfo.getTableName());
				syncTask.setRecordId(syncInfo.getRecordId());
				syncTask.setOpt(syncInfo.getOpt());
				syncTask.setStatus(1);
				syncTask.setCreateTime(new Date());
				syncTask.setUpdateTime(new Date());
				taskService.insert(syncTask);
				
				syncInfo.setStatus(2);
				syncInfoservice.updateById(syncInfo);
			}
			
			Wrapper<FaceSyncTask> syncWrapper = new EntityWrapper<>();
			syncWrapper.eq("status", 1);
			List<FaceSyncTask> taskList = taskService.selectList(syncWrapper);

			for (FaceSyncTask task : taskList) {
				MqttMessage mqttMessage = new MqttMessage();
				mqttMessage.setQos(2);
				mqttMessage.setRetained(true);

				if (task.getTableName().equals("face_person")) {
					FacePerson person = facePersonService.selectById(task.getRecordId());
					PayLoad payload = new PayLoad();
					payload.setName("face_person");
					payload.setRecord(person);
					payload.setOpt(task.getOpt().toString());
					
					StringBuilder payloadStr = new StringBuilder();
					payloadStr.append("face_person:");
					payloadStr.append(JSON.toJSONString(payload));
//					payloadStr.append("}");

					log.info(payloadStr.toString());
					result.append(payloadStr + "\n");
					mqttMessage.setPayload(payloadStr.toString().getBytes());
					
//					mqttMessage.setPayload(payload.toString().getBytes());
					

				}
				if (task.getTableName().equals("face_photo_lib")) {
					FacePhotoLib photoLib = facePhotoLibService.selectById(task.getRecordId());
					log.info("photoDir:"+SysConfig.photoDir);
					if(task.getOpt().intValue() != 2) {
						File imgFilePath = new File(SysConfig.photoDir + photoLib.getPhoto());// 获取图片库内的图片地址
						if (imgFilePath.exists()) {
							InputStream in = null;
							byte[] photoData = null;
							try {
								in = new FileInputStream(imgFilePath);
								photoData = new byte[in.available()];
								in.read(photoData);
								in.close();
							} catch (Exception e) {
								log.error("photo inputStrean", e);
							}
							String photoBase64 = Base64.encodeBase64String(photoData);
//							photoLib.setPhoto(photoBase64);
//							photoLib.setVec(photoBase64);
							photoLib.setPhotoBase64(photoBase64);
						}
					}
					
					PayLoad payload = new PayLoad();
					payload.setName("face_photo_lib");
					payload.setRecord(photoLib);
					payload.setOpt(task.getOpt().toString());

					StringBuilder payloadStr = new StringBuilder();
					payloadStr.append("face_photo_lib:");
					payloadStr.append(JSON.toJSONString(payload));
//					payloadStr.append("}");

					log.info(payloadStr.toString());
					result.append(payloadStr + "\n");
					mqttMessage.setPayload(payloadStr.toString().getBytes());
//					mqttMessage.setPayload(payload.toString().getBytes());
					

				}
				if (task.getTableName().equals("face_vehicle")) {
					FaceVehicle vehicle = faceVehicleService.selectById(task.getRecordId());
					PayLoad payload = new PayLoad();
					payload.setName("face_vehicle");
					payload.setRecord(vehicle);
					payload.setOpt(task.getOpt().toString());

					StringBuilder payloadStr = new StringBuilder();
					payloadStr.append("face_vehicle:");
					payloadStr.append(JSON.toJSONString(payload));
//					payloadStr.append("}");

					log.info(payloadStr.toString());
					result.append(payloadStr + "\n");
					mqttMessage.setPayload(payloadStr.toString().getBytes());
//					mqttMessage.setPayload(payload.toString().getBytes());
					

				}
				if (task.getTableName().equals("face_schedule")) {
					FaceSchedule schedule = faceScheduleService.selectById(task.getRecordId());
					PayLoad payload = new PayLoad();
					payload.setName("face_schedule");
					payload.setRecord(schedule);
					payload.setOpt(task.getOpt().toString());

					StringBuilder payloadStr = new StringBuilder();
					payloadStr.append("face_schedule:");
					payloadStr.append(JSON.toJSONString(payload));
//					payloadStr.append("}");

					log.info(payloadStr.toString());
					result.append(payloadStr + "\n");
					mqttMessage.setPayload(payloadStr.toString().getBytes());
//					mqttMessage.setPayload(payload.toString().getBytes());
					

				}

				service.publish(mqttMessage, task.getVehicleNo());
				task.setStatus(2);
				taskService.updateById(task);
			}//end for
		} catch (MqttPersistenceException e) {
			baseResult.fail(e.getMessage());
			log.info("",e);

		} catch (MqttException e) {
			baseResult.fail(e.getMessage());
			log.info("",e);
		}

		return baseResult.success(result);
	}

	@RequestMapping("publish")
	private void servicePublish(MqttMessage message, String topic) {
		try {
			service.publish(message, topic);
		} catch (MqttException e) {
			log.error("publish:", e);
		}
	}

	@RequestMapping("subscribe")
	private void serviceSubscribe(int qos, String topic) {
		try {
			service.subscribe(qos, topic);
		} catch (MqttException e) {
			log.error("subscribe:", e);
		}
	}

}

class PayLoad {
	private String name;
	private String opt;
	private Object record;

	public String getName() {
		return name;
	}

	public void setName(String name) {
		this.name = name;
	}

	public Object getRecord() {
		return record;
	}

	public void setRecord(Object record) {
		this.record = record;
	}

	public String getOpt() {
		return opt;
	}

	public void setOpt(String opt) {
		this.opt = opt;
	}
}